package com.adms.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.adms.domain.Message;
import com.adms.domain.MessageMapper;
import com.adms.domain.Reform;
import com.adms.domain.ReformDelay;
import com.adms.domain.ReformDelayExample;
import com.adms.domain.ReformDelayExample.Criteria;
import com.adms.domain.ReformDelayMapper;
import com.adms.domain.ReformMapper;
import com.adms.domain.User;
import com.adms.util.AdmsConfig;
import com.adms.util.ShiroUtil;
import com.adms.websocket.WebSocketServer;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;

@Transactional
@Service
public class ReformDelayService {

	@Autowired
	private ReformDelayMapper reformDelayMapper;
	@Autowired
	private ReformMapper reformMapper;
	@Autowired
	private MessageMapper messageMapper;
	@Autowired
	private WebSocketServer webSocketServer;

	public ReformDelay getByDelayId(Integer delayId) {
		return reformDelayMapper.selectByPrimaryKey(delayId);
	}

	public Map<String, Object> getByDelayIdWithReform(Integer delayId) {
		return reformDelayMapper.selectByPrimaryKeyWithReform(delayId);
	}

	public PageInfo<ReformDelay> list(ReformDelay reformDelay, String timeField, Date start, Date end,
			String orderByClause, Integer pageNum, Integer pageSize, Integer navigatePages) {

		ReformDelayExample ex = constructExample(reformDelay, timeField, start, end, orderByClause);
		PageHelper.startPage(pageNum, pageSize);
		List<ReformDelay> reformDelays = reformDelayMapper.selectByExample(ex);
		return new PageInfo<>(reformDelays, navigatePages);
	}

	private ReformDelayExample constructExample(ReformDelay reformDelay, String timeField, Date start, Date end,
			String orderByClause) {
		ReformDelayExample ex = new ReformDelayExample();
		Criteria or = ex.or();
		if (reformDelay != null) {
			Integer reformId = reformDelay.getReformId();
			Integer gridAuditState = reformDelay.getGridAuditState();
			Integer envAuditState = reformDelay.getEnvAuditState();
			if (reformId != null) {
				or.andReformIdEqualTo(reformId);
			}
			if (gridAuditState != null) {
				or.andGridAuditStateEqualTo(gridAuditState);
			}
			if (envAuditState != null) {
				or.andEnvAuditStateEqualTo(envAuditState);
			}
		}

		if (StringUtil.isNotEmpty(timeField)) {
			if (timeField.equals("delayTime")) {
				if (start != null) {
					if (end != null) {
						or.andDelayTimeBetween(start, end);
					} else {
						or.andDelayTimeGreaterThanOrEqualTo(start);
					}
				} else {
					if (end != null) {
						or.andDelayTimeLessThanOrEqualTo(end);
					}
				}
			}
			if (timeField.equals("createTime")) {
				if (start != null) {
					if (end != null) {
						or.andCreateTimeBetween(start, end);
					} else {
						or.andCreateTimeGreaterThanOrEqualTo(start);
					}
				} else {
					if (end != null) {
						or.andCreateTimeLessThanOrEqualTo(end);
					}
				}
			}
			if (timeField.equals("gridAuditTime")) {
				if (start != null) {
					if (end != null) {
						or.andGridAuditTimeBetween(start, end);
					} else {
						or.andGridAuditTimeGreaterThanOrEqualTo(start);
					}
				} else {
					if (end != null) {
						or.andGridAuditTimeLessThanOrEqualTo(end);
					}
				}
			}
			if (timeField.equals("envAuditTime")) {
				if (start != null) {
					if (end != null) {
						or.andEnvAuditTimeBetween(start, end);
					} else {
						or.andEnvAuditTimeGreaterThanOrEqualTo(start);
					}
				} else {
					if (end != null) {
						or.andEnvAuditTimeLessThanOrEqualTo(end);
					}
				}
			}
		}

		if (StringUtil.isNotEmpty(orderByClause)) {
			ex.setOrderByClause(orderByClause);
		} else {
			ex.setOrderByClause("reform_delay.create_time desc");
		}
		return ex;
	}

	public boolean audit(Integer delayId, Integer reformId, Integer auditState, String auditView) {
		User loginUser = ShiroUtil.getUser();
		String loginRole = loginUser.getRole();
		Integer loginUserId = loginUser.getUserId();
		Reform reform = reformMapper.selectByPrimaryKey(reformId);
		ReformDelay reformDelay = reformDelayMapper.selectByPrimaryKey(delayId);
		if (reformDelay.getGridAuditState() != 1 && loginUserId.equals(reform.getGridUserId())) {
			gridAudit(reform, reformDelay, delayId, reformId, auditState, auditView);
		} else if (reformDelay.getEnvAuditState() != 1 && (loginRole.equals(AdmsConfig.ROLE_ENVDEPARTMENT)
				|| loginRole.equals(AdmsConfig.ROLE_ENVLEADER) || loginRole.equals(AdmsConfig.ROLE_OFFICELEADER))) {
			envAudit(reform, reformDelay, delayId, reformId, auditState, auditView);
		}
		return true;
	}

	private void gridAudit(Reform reform,ReformDelay reformDelay,Integer delayId, Integer reformId, Integer auditState, String auditView) {
		// 更新审核单
		reformDelay.setGridAuditState(auditState);
		reformDelay.setGridAuditView(auditView);
		reformDelay.setGridAuditTime(new Date());
		reformDelayMapper.updateByPrimaryKeySelective(reformDelay);
		// 新增站内信
		Integer envUserId = reform.getUserId();
		List<Integer> relativeUserIds = new ArrayList<>();
		relativeUserIds.add(reform.getHandleUserId());
		relativeUserIds.add(reform.getLegalUserId());
		Message message = new Message();
		message.setReformId(reformId);
		message.setDelayId(delayId);
		message.setTitle(reform.getTitle());
		// 审核通过
		if (auditState == 1) {
			message.setType(AdmsConfig.MESSAGE_TYPE_DEFERREFORM_PASS_BYGRID);
			// 加入环安科,因为要通知到环安科,交办人,负责人
			relativeUserIds.add(envUserId);
		}
		// 审核拒绝
		if (auditState == 2) {
			message.setType(AdmsConfig.MESSAGE_TYPE_DEFERREFORM_FAIL_BYGRID);
			// 更新整改单可申请延期为true
			reform.setCanDefer(true);
			reformMapper.updateByPrimaryKey(reform);
		}
		for (Integer relativeUserId : relativeUserIds) {
			message.setUserId(relativeUserId);
			messageMapper.insertSelective(message);
			// 发送webSocket消息
			webSocketServer.sendMessage(relativeUserId, message);
			// 重置获取主键id为null
			message.setMessageId(null);
		}
	}

	private void envAudit(Reform reform,ReformDelay reformDelay,Integer delayId, Integer reformId, Integer auditState, String auditView) {
		// 获取并更新延期单
		reformDelay.setEnvAuditState(auditState);
		reformDelay.setEnvAuditView(auditView);
		reformDelay.setEnvAuditTime(new Date());
		reformDelayMapper.updateByPrimaryKey(reformDelay);
		// 新增站内信
		List<Integer> relativeUserIds = new ArrayList<>();
		relativeUserIds.add(reform.getGridUserId());
		relativeUserIds.add(reform.getHandleUserId());
		relativeUserIds.add(reform.getLegalUserId());
		Message message = new Message();
		message.setReformId(reformId);
		message.setDelayId(delayId);
		message.setTitle(reform.getTitle());
		// 审核通过
		if (auditState == 1) {
			message.setType(AdmsConfig.MESSAGE_TYPE_DEFERREFORM_PASS_BYENV);
			// 修改整改单结束时间为申请的延期时间
			Date delayTime = reformDelay.getDelayTime();
			Date maxEndTime = reform.getMaxEndTime();
			if (delayTime.after(maxEndTime)) {
				throw new RuntimeException("延期时间不能超过最大允许时间");
			}
			reform.setEndTime(delayTime);
			// 修改整改单的提醒标识为false
			reform.setHasReminded(false);
		}
		// 审核拒绝
		if (auditState == 2) {
			message.setType(AdmsConfig.MESSAGE_TYPE_DEFERREFORM_FAIL_BYENV);
		}
		for (Integer relativeUserId : relativeUserIds) {
			message.setUserId(relativeUserId);
			messageMapper.insertSelective(message);
			webSocketServer.sendMessage(relativeUserId, message);
			message.setMessageId(null);
		}
		// 更新整改单可申请延期为true
		reform.setCanDefer(true);
		reformMapper.updateByPrimaryKey(reform);
	}
}
